package org.example.platform.genter;


import org.example.platform.dto.UserDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.util.StringUtils;

import javax.security.auth.message.AuthException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 短信验证码登录
 *
 * @author 向振华
 * @date 2021/04/06 10:11
 */
public class SMSCodeTokenGranter extends AbstractTokenGranter {
    private static final String GRANT_TYPE = "sms";
    @Autowired
    PasswordEncoder passwordEncoder;

    public SMSCodeTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) {
        super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
    }

    public void setPasswordEncoder(PasswordEncoder passwordEncoder){
        this.passwordEncoder=passwordEncoder;
    }

    @Override
    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
        Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());
        // 校验短信验证码
        try {
            this.verifySms(parameters);
        } catch (AuthException e) {
            throw new RuntimeException(e);
        }
        // 登录用户信息
        String username = (String) parameters.get("username");
        String credentials = (String) parameters.get("verifyCode");
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("admin"));

        UserDto userInfo = new UserDto(1, "1523211", "123456", authorities);

        PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(userInfo, null, authorities);
        authentication.setDetails(userInfo);

        OAuth2Request storedOAuth2Request = this.getRequestFactory().createOAuth2Request(client, tokenRequest);
        return new OAuth2Authentication(storedOAuth2Request, authentication);
    }

    /**
     * 校验短信验证码
     *
     * @param parameters
     */
    private void verifySms(Map<String, String> parameters) throws AuthException {
        String username = (String) parameters.get("username");
        String code = (String) parameters.get("code");
        if (StringUtils.isEmpty(username)) {
            throw new AuthException("手机号不能为空");
        }
        if (StringUtils.isEmpty(code)) {
            throw new AuthException("验证码不能为空");
        }
        // TODO 根据手机号获取redis验证码
        String codeCache = "123456";
        if (StringUtils.isEmpty(codeCache)) {
            throw new AuthException("验证码已失效，请重新获取");
        }
        if (!code.equals(codeCache)) {
            throw new AuthException("验证码错误");
        }
    }

}
